package com.pateo.bjev.contacts.utils;

import android.content.Context;
import android.text.TextUtils;

import com.pateo.bluetooth.logic.bean.ContactData;
import com.pateo.bluetooth.logic.bean.PhoneNumber;
import com.pateo.bluetooth.logic.contact.manager.ContactsManager;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.LinkedList;
import java.util.List;
import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.functions.Predicate;
import io.reactivex.schedulers.Schedulers;

/**
 * 搜索联系人工具类，抽象父类
 * Created by pateo on 17-5-11.
 */

public abstract class ContactSearchUtils<T>{

    Context mContext;
    ObservableEmitter<String> searchNumEmitter;
    Observable<String> searchNumOb;
    SearchCallback<T> callback;

    public ContactSearchUtils(Context context){

        this.mContext = context;
        searchNumOb = Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> observableEmitter) throws Exception {
                searchNumEmitter = observableEmitter;
            }
        }).subscribeOn(Schedulers.newThread()).observeOn(AndroidSchedulers.mainThread(),false,100);

        searchNumOb.filter(new Predicate<String>() {
            @Override
            public boolean test(String s) throws Exception {
                if(TextUtils.isEmpty(s)){
                    return true;
                }
                return false;
            }
        }).map(new Function<String, List<T>>() {
            @Override
            public List<T> apply(String s) throws Exception {
                return searchContacts(s);
            }
        }).subscribe(new Consumer<List<T>>() {
            @Override
            public void accept(List<T> searchNumResults) throws Exception {
                if(callback==null || searchNumResults == null){
                    return;
                }
                if(searchNumResults.size()>0){
                    callback.onSearchOne(searchNumResults.get(0));
                }
                callback.onSearchResult(searchNumResults);
            }
        });
    }

    /**
     * 子类具体实现搜索逻辑
     * @param key
     * @return
     */
    public abstract List<T> searchContacts(String key);

    /**
     * 外部搜索入口
     * @param key
     * @param callback
     */
    public void searchContacts(String key,SearchCallback<T> callback){
        if(TextUtils.isEmpty(key)){
            return;
        }
        this.callback = callback;
        if(searchNumEmitter!=null){
            searchNumEmitter.onNext(key);
        }
    }

    /**
     * 搜索回调
     * @param <T>
     */
    public interface SearchCallback<T>{
        void onSearchResult(List<T> list);
        void onSearchOne(T t);
    }

    /**
     * 按照名字来搜索联系人
     */
    public static class SearchNameUtils extends ContactSearchUtils<ContactData>{

        public SearchNameUtils(Context context) {
            super(context);
        }

        @Override
        public List<ContactData> searchContacts(String key) {
            List<ContactData> results = new LinkedList<>();
            if(TextUtils.isEmpty(key)){
                return results;
            }
            List<ContactData> allContacts = ContactsManager.getInstance(mContext.getApplicationContext()).getContactsList();
            for(ContactData data : allContacts){
                if(data.getPinYin()!=null && data.getPinYin().toUpperCase().indexOf(key.toUpperCase())!=-1){
                    results.add(data);
                    continue;
                }
                if(data.getPinYinHead()!=null && data.getPinYinHead().toUpperCase().indexOf(key.toUpperCase())!=-1){
                    results.add(data);
                    continue;
                }

                if(data.getName()!=null && data.getName().toUpperCase().indexOf(key.toUpperCase())!=-1){
                    results.add(data);
                    continue;
                }
            }
            return results;
        }
    }

    /**
     * 按照电话号来搜索联系人
     */
    public static class SearchNumUtils extends ContactSearchUtils<ContactSearchUtils.SearchNumResult>{

        public SearchNumUtils(Context context) {
            super(context);
        }

        @Override
        public List<ContactSearchUtils.SearchNumResult> searchContacts(String key) {
            List<ContactSearchUtils.SearchNumResult> results = new LinkedList<>();
            if(TextUtils.isEmpty(key)|| key.length()<2){
                return results;
            }
            List<ContactData> allContacts = ContactsManager.getInstance(mContext.getApplicationContext()).getContactsList();
            for(ContactData data : allContacts){
                List<PhoneNumber> numbers = data.getPhoneNumList();
                for(PhoneNumber n : numbers){
                    if(n.getNumber().indexOf(key)!=-1){
                        SearchNumResult result = new SearchNumResult(data.getName(),n.getNumber());
                        results.add(result);
                    }
                }
            }
            return results;
        }
    }

    /**
     * 搜索电话号包装对象
     */
    public class SearchNumResult{
        String name;
        String number;

        public SearchNumResult(String name, String number) {
            this.name = name;
            this.number = number;
        }

        public String getNumber() {
            return number;
        }

        public void setNumber(String number) {
            this.number = number;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }
}
